home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / lang / amigatalk.lha / system / ESemaphore.st < prev    next >
Text File  |  2002-03-25  |  11KB  |  227 lines

  1. " ---------------------------------------------------------------------- "
  2. " The ESemaphore class implements exec.library semaphore functions into  "
  3. " AmigaTalk.  This Class is NOT the same as the Semaphore Class in       "
  4. " AmigaTalk:General/Semaphore.st                                         "
  5. " ---------------------------------------------------------------------- "
  6.  
  7. Class ESemaphore :Object ! private semMsgObj !
  8. [
  9.    create: semName priority: semaphorePriority
  10.       ^ private <- <primitive 209 5 1 semName semaphorePriority>
  11. |
  12.    dispose
  13.       <primitive 209 5 0 private>.
  14.       private <- nil
  15. |
  16.    getESemaphore
  17.       ^ private
  18. |
  19.    createSemaphoreMsg: signalSemaphoreObj
  20.       ^ semMsgObj <- <primitive 209 5 2 signalSemaphoreObj>
  21. |
  22.    disposeSemaphoreMsg
  23.       <primitive 209 5 0 semMsgObj>
  24. |
  25.    getSemaphoreMessage
  26.       ^ semMsgObj
  27. |
  28.    obtainSharedSemaphore: signalSemaphoreObj
  29.       " A lock on a signal semaphore may either be exclusive, or shared.
  30.       * Exclusive locks are granted by the obtainSemaphore: and
  31.       * attemptSemaphore: methods.  Shared locks are granted by
  32.       * obtainSemaphoreShared:.  Calls may be nested.
  33.       *
  34.       * Any number of tasks may simultaneously hold a shared lock on a
  35.       * semaphore.  Only one task may hold an exclusive lock.  A typical
  36.       * application is a list that is often read, but only occasionally
  37.       * written to.
  38.       *
  39.       * Any exlusive locker will be held off until all shared lockers
  40.       * release the semaphore.  Likewise, if an exlusive lock is held,
  41.       * all potential shared lockers will block until the exclusive lock
  42.       * is released.  All shared lockers are restarted at the same time.
  43.       "
  44.       <primitive 209 4 80 signalSemaphoreObj>
  45. |
  46.    procure: signalSemaphoreObj msg: semaphoreMsgObj
  47.       " This method is used to obtain a semaphore in an async manner.
  48.       * Like obtainSemaphore:, it will obtain a SignalSemaphore for you
  49.       * but unlike obtainSemaphore:, you will not block until you get
  50.       * the semaphore.  procure:msg: will just post a request for the semaphore
  51.       * and will return.  When the semaphore is available (which could
  52.       * be at any time) the bidMessage will ReplyMsg() and you will own
  53.       * the semaphore.  This lets you wait on multiple semaphores at once
  54.       * and to continue processing while waiting for the semaphore.
  55.       *
  56.       * NOTE:  Pre-V39, Procure() and Vacate() did not work correctly.
  57.       * They also did not operate on SignalSemaphore semaphores.
  58.       * Old (and broken) MessageSemaphore use as of V39 will no longer work.
  59.       "
  60.       ^ <primitive 209 4 63 signalSemaphoreObj semaphoreMsgObj>
  61. |
  62.    vacate: signalSemaphoreObj msg: semaphoreMsgObj
  63.       " This method can be used to release a semaphore obtained via
  64.       * procure:msg:.  However, the main purpose for this call is to be
  65.       * able to remove a bid for a semaphore that has not yet responded.
  66.       * This is required when a Procure() was issued and the program
  67.       * no longer needs to get the semaphore and wishes to cancel the
  68.       * Procure() request.  The canceled request will be replied with
  69.       * the ssm_Semaphore field set to NULL.  If you own the semaphore,
  70.       * the message was already replied and only the ssm_Semaphore field
  71.       * will be cleared.
  72.       *
  73.       * NOTE:  Pre-V39, Procure() and Vacate() did not work correctly.
  74.       * They also did not operate on SignalSemaphore semaphores.
  75.       * Old (and broken) MessageSemaphore use as of V39 will no longer work.
  76.       "
  77.       <primitive 209 4 64 signalSemaphoreObj semaphoreMsgObj>
  78. |
  79.    initSemaphore: signalSemaphoreObj
  80.       " This method initializes a signal semaphore and prepares it for
  81.       * use.  It does not allocate anything, but does initialize list
  82.       * pointers and the semaphore counters.
  83.       *
  84.       * Semaphores are often used to protect critical data structures
  85.       * or hardware that can only be accessed by one task at a time.
  86.       * After initialization, the address of the SignalSemaphore may be
  87.       * made available to any number of tasks.  Typically a task will
  88.       * try to obtainSemaphore:, passing this address in.  If no other
  89.       * task owns the semaphore, then the call will lock and return
  90.       * quickly.  If more tasks try to obtainSemaphore:, they will
  91.       * be put to sleep.  When the owner of the semaphore releases
  92.       * it, the next waiter in turn will be woken up.
  93.       *
  94.       * Semaphores are often preferable to the old-style Forbid()/Permit()
  95.       * type arbitration.  With Forbid()/Permit() *all* other tasks are
  96.       * prevented from running.  With semaphores, only those tasks that
  97.       * need access to whatever the semaphore protects are subject
  98.       * to waiting.
  99.       "
  100.       <primitive 209 4 65 signalSemaphoreObj>
  101. |
  102.    obtainSemaphore: signalSemaphoreObj
  103.       " Signal semaphores are used to gain exclusive access to an object.
  104.       * obtainSemaphore: is the method used to gain this access.  If another
  105.       * user currently has the semaphore locked the call will block until
  106.       * the object is available.
  107.       *
  108.       * If the current task already has locked the semaphore and attempts to
  109.       * lock it again the call will still succeed.  A "nesting count" is
  110.       * incremented each time the current owning task of the semaphore calls
  111.       * obtainSemaphore:.  This counter is decremented each time
  112.       * releaseSemaphore: is called.  When the counter returns to zero the
  113.       * semaphore is actually released, and the next waiting task is called.
  114.       *
  115.       * A queue of waiting tasks is maintained on the stacks of the waiting
  116.       * tasks.    Each will be called in turn as soon as the current task
  117.       * releases the semaphore.
  118.       *
  119.       * Signal Semaphores are different than Procure()/Vacate() semaphores.
  120.       * The former requires less CPU time, especially if the semaphore is
  121.       * not currently locked.  They require very little set up and user
  122.       * thought.  The latter flavor of semaphore make no assumptions about
  123.       * how they are used -- they are completely general.  Unfortunately
  124.       * they are not as efficient as signal semaphores, and require the
  125.       * locker to have done some setup before doing the call.
  126.       "
  127.       <primitive 209 4 66 signalSemaphoreObj>
  128. |
  129.    releaseSemaphore: signalSemaphoreObj
  130.       " releaseSemaphore: is the inverse of obtainSemaphore:. It makes
  131.       * the semaphore lockable to other users.    If tasks are waiting for
  132.       * the semaphore and this this task is done with the semaphore then
  133.       * the next waiting task is signalled.
  134.       *
  135.       * Each obtainSemaphore: call must be balanced by exactly one
  136.       * releaseSemaphore: call.  This is because there is a nesting count
  137.       * maintained in the semaphore of the number of times that the current
  138.       * task has locked the semaphore. The semaphore is not released to
  139.       * other tasks until the number of releases matches the number of
  140.       * obtains.
  141.       *
  142.       * Needless to say, havoc breaks out if the task releases more times
  143.       * than it has obtained.
  144.       "
  145.       <primitive 209 4 67 signalSemaphoreObj>
  146. |
  147.    attemptSemaphore: signalSemaphoreObj
  148.       " This call is similar to obtainSemaphore:, except that 
  149.       * it will not block if the semaphore could not be locked.
  150.       *
  151.       * Returns true if the semaphore was locked, false if some
  152.       * other task already possessed the semaphore.
  153.       "
  154.       ^ <primitive 209 4 68 signalSemaphoreObj>
  155. |
  156.    obtainSemaphoreList: listObj
  157.       " Signal semaphores may be linked together into a list. This function
  158.       * takes a list of these semaphores and attempts to lock all of them at
  159.       * once. This call is preferable to applying obtainSemaphore: to each
  160.       * element in the list because it attempts to lock all the elements
  161.       * simultaneously, and won't deadlock if someone is attempting to lock
  162.       * in some other order.
  163.       *
  164.       * This function assumes that only one task at a time will attempt to
  165.       * lock the entire list of semaphores.  In other words, there needs to
  166.       * be a higher level lock (perhaps another signal semaphore...) that is
  167.       * used before someone attempts to lock the semaphore list via
  168.       * obtainSemaphoreList:.
  169.       *
  170.       * Note that deadlocks may result if this call is used AND someone
  171.       * attempts to use obtainSemaphore: to lock more than one semaphore on
  172.       * the list.  If you wish to lock more than semaphore (but not all of
  173.       * them) then you should obtain the higher level lock (see above)
  174.       " 
  175.       <primitive 209 4 69 listObj>
  176. |
  177.    releaseSemaphoreList: listObj
  178.       " releaseSemaphoreList: is the inverse of obtainSemaphoreList:. It
  179.       * releases each element in the semaphore list.
  180.       *
  181.       * Needless to say, havoc breaks out if the task releases more times
  182.       * than it has obtained.
  183.       "
  184.       <primitive 209 4 70 listObj>
  185. |
  186.    findSemaphore: semaphoreName
  187.       " This function will search the system signal semaphore list for a
  188.       * semaphore with the given name.    The first semaphore matching this
  189.       * name will be returned.
  190.       *
  191.       * This function does not arbitrate for access to the semaphore list,
  192.       * surround the call with a Forbid()/Permit() pair.
  193.       "
  194.       ^ <primitive 209 4 71 semaphoreName>
  195. |
  196.    addSemaphore: signalSemaphoreObj
  197.       " This method attaches a signal semaphore structure to the system's
  198.       * public signal semaphore list.  The name and priority fields of the
  199.       * semaphore structure must be initialized prior to calling this
  200.       * method.  If you do not want to let others rendezvous with this
  201.       * semaphore, use initSemaphore: instead.
  202.       *
  203.       * If a semaphore has been added to the naming list, you must be
  204.       * careful to remove the semaphore from the list (via removeSemaphore:)
  205.       * before deallocating its memory.
  206.       *
  207.       * Semaphores that are linked together in an allocation list (which
  208.       * obtainSemaphoreList: would use) may not be added to the system
  209.       * naming list, because the facilities use the link field of the
  210.       * signal semaphore in incompatible ways
  211.       "
  212.       <primitive 209 4 72 signalSemaphoreObj>
  213. |
  214.    removeSemaphore: signalSemaphoreObj
  215.       " This method removes a signal semaphore structure from the
  216.       * system's signal semaphore list.  Subsequent attempts to
  217.       * rendezvous by name with this semaphore will fail.
  218.       "
  219.       <primitive 209 4 73 signalSemaphoreObj>
  220. |
  221.    attemptSemaphoreShared: signalSemaphoreObj
  222.       " This method is similar to obtainSharedSemaphore:, except that it
  223.       * will not block if the semaphore could not be locked.
  224.       "
  225.       ^ <primitive 209 4 74 signalSemaphoreObj>
  226. ]
  227.